home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / SRC / ASM_386.S < prev    next >
Encoding:
Text File  |  1998-07-09  |  34.9 KB  |  1,865 lines

  1. /* $Id: asm_386.S,v 3.2 1998/05/31 23:33:56 brianp Exp $ */
  2.  
  3. /*
  4.  * asm-386.S - special (hopefully faster) transformation functions for x86
  5.  *
  6.  * by Josh Vanderhoof
  7.  *
  8.  * This file is in the public domain.
  9.  */
  10.  
  11. /*
  12.  * $Log: asm_386.S,v $
  13.  * Revision 3.2  1998/05/31 23:33:56  brianp
  14.  * small change for OS/2 from Alexander Mai
  15.  *
  16.  * Revision 3.1  1998/03/05 03:08:32  brianp
  17.  * added Josh's patches for rescale normal feature
  18.  *
  19.  * Revision 3.0  1998/01/31 20:45:56  brianp
  20.  * initial rev
  21.  *
  22.  * Revision 1.8  1997/12/17 00:50:51  brianp
  23.  * applied Josh's patch to fix texture coordinate transformation bugs
  24.  *
  25.  * Revision 1.7  1997/12/17 00:27:11  brianp
  26.  * applied Josh's patch to fix bfris
  27.  *
  28.  * Revision 1.6  1997/12/01 01:02:41  brianp
  29.  * added FreeBSD patches (Daniel J. O'Connor)
  30.  *
  31.  * Revision 1.5  1997/11/19 23:52:17  brianp
  32.  * added missing "cld" instruction in asm_transform_points4_identity()
  33.  *
  34.  * Revision 1.4  1997/11/11 02:22:41  brianp
  35.  * small change per Josh to ensure U/V pairing
  36.  *
  37.  * Revision 1.3  1997/11/07 03:37:24  brianp
  38.  * added missing line from Stephane Rehel
  39.  *
  40.  * Revision 1.2  1997/11/07 03:30:37  brianp
  41.  * added Josh's 11-5-97 patches
  42.  *
  43.  * Revision 1.1  1997/10/30 06:00:33  brianp
  44.  * Initial revision
  45.  */
  46.  
  47.  
  48. #ifndef ALIGN
  49. #define ALIGN     .align 4, 0x90
  50. #endif
  51.  
  52. #ifndef GLOBAL
  53. #define GLOBAL(n)     .globl n
  54. #endif
  55.  
  56. /*
  57.  * Change this to .data if your system doesn't have .rodata
  58.  */
  59. #ifndef RODATA
  60. #if defined(FREEBSD) || defined(__EMX__)
  61. #define RODATA .data
  62. #else
  63. #define RODATA     .section .rodata
  64. #endif
  65. #endif
  66.  
  67. #ifndef DATA
  68. #define DATA     .data
  69. #endif
  70.  
  71. #ifndef TEXT
  72. #define TEXT     .text
  73. #endif
  74.  
  75.  
  76. #define S(x)     x * 4(%esi)
  77. #define D(x)     x * 4(%edi)
  78. #define M(x, y) x * 16 + y * 4(%edx)
  79.  
  80. /*
  81.  * void asm_transform_points3_general( GLuint n, GLfloat d[][4],
  82.  *                                     GLfloat m[16], GLfloat s[][4] );
  83.  */
  84. #ifdef FREEBSD
  85. GLOBAL(_asm_transform_points3_general)
  86. ALIGN
  87. _asm_transform_points3_general:
  88. #else
  89. GLOBAL(asm_transform_points3_general)
  90. ALIGN
  91. asm_transform_points3_general:
  92. #endif
  93.     pushl %esi
  94.     pushl %edi
  95.     movl 12(%esp), %ecx     /* ecx = n */
  96.     movl 16(%esp), %edi     /* edi = d */
  97.     movl 20(%esp), %edx     /* edx = m */
  98.     movl 24(%esp), %esi     /* esi = s */
  99.  
  100.     testl %ecx, %ecx
  101.     jz 2f
  102.  
  103. ALIGN
  104. 1:    flds S(0)
  105.     fmuls M(0, 0)
  106.     flds S(0)
  107.     fmuls M(0, 1)
  108.     flds S(0)
  109.     fmuls M(0, 2)
  110.     flds S(0)
  111.     fmuls M(0, 3)
  112.  
  113.     flds S(1)
  114.     fmuls M(1, 0)
  115.     flds S(1)
  116.     fmuls M(1, 1)
  117.     flds S(1)
  118.     fmuls M(1, 2)
  119.     flds S(1)
  120.     fmuls M(1, 3)
  121.  
  122.     /*
  123.      * The FPU stack should now look like this:
  124.      *
  125.      * st(7) = S(0) * M(0, 0)
  126.      * st(6) = S(0) * M(0, 1)
  127.      * st(5) = S(0) * M(0, 2)
  128.      * st(4) = S(0) * M(0, 3)
  129.      * st(3) = S(1) * M(1, 0)
  130.      * st(2) = S(1) * M(1, 1)
  131.      * st(1) = S(1) * M(1, 2)
  132.      * st(0) = S(1) * M(1, 3)
  133.      */
  134.  
  135.     fxch %st(3)        /* 3 1 2 0 4 5 6 7 */
  136.     faddp %st, %st(7)     /* 1 2 0 4 5 6 7 */
  137.     fxch %st(1)        /* 2 1 0 4 5 6 7 */
  138.     faddp %st, %st(5)     /* 1 0 4 5 6 7 */
  139.     faddp %st, %st(3)     /* 0 4 5 6 7 */
  140.     faddp %st, %st(1)     /* 4 5 6 7 */
  141.  
  142.     /*
  143.      * st(3) = S(0) * M(0, 0) + S(1) * M(1, 0)
  144.      * st(2) = S(0) * M(0, 1) + S(1) * M(1, 1)
  145.      * st(1) = S(0) * M(0, 2) + S(1) * M(1, 2)
  146.      * st(0) = S(0) * M(0, 3) + S(1) * M(1, 3)
  147.      */
  148.  
  149.     flds S(2)
  150.     fmuls M(2, 0)
  151.     flds S(2)
  152.     fmuls M(2, 1)
  153.     flds S(2)
  154.     fmuls M(2, 2)
  155.     flds S(2)
  156.     fmuls M(2, 3)
  157.  
  158.     /*
  159.      * st(7) = S(0) * M(0, 0) + S(1) * M(1, 0)
  160.      * st(6) = S(0) * M(0, 1) + S(1) * M(1, 1)
  161.      * st(5) = S(0) * M(0, 2) + S(1) * M(1, 2)
  162.      * st(4) = S(0) * M(0, 3) + S(1) * M(1, 3)
  163.      * st(3) = S(2) * M(2, 0)
  164.      * st(2) = S(2) * M(2, 1)
  165.      * st(1) = S(2) * M(2, 2)
  166.      * st(0) = S(2) * M(2, 3)
  167.      */
  168.  
  169.     fxch %st(3)        /* 3 1 2 0 4 5 6 7 */
  170.     faddp %st, %st(7)     /* 1 2 0 4 5 6 7 */
  171.     fxch %st(1)        /* 2 1 0 4 5 6 7 */
  172.     faddp %st, %st(5)     /* 1 0 4 5 6 7 */
  173.     faddp %st, %st(3)     /* 0 4 5 6 7 */
  174.     faddp %st, %st(1)     /* 4 5 6 7 */
  175.  
  176.     /*
  177.      * st(3) = S(0) * M(0, 0) + S(1) * M(1, 0) + S(2) * M(2, 0)
  178.      * st(2) = S(0) * M(0, 1) + S(1) * M(1, 1) + S(2) * M(2, 1)
  179.      * st(1) = S(0) * M(0, 2) + S(1) * M(1, 2) + S(2) * M(2, 2)
  180.      * st(0) = S(0) * M(0, 3) + S(1) * M(1, 3) + S(2) * M(2, 3)
  181.      */
  182.  
  183.     fxch %st(3)     /* 3 1 2 0 */
  184.     fadds M(3, 0)
  185.     fxch %st(2)     /* 2 1 3 0 */
  186.     fadds M(3, 1)
  187.     fxch %st(1)     /* 1 2 3 0 */
  188.     fadds M(3, 2)
  189.     fxch %st(3)     /* 0 2 3 1 */
  190.     fadds M(3, 3)
  191.  
  192.     /*
  193.      * st(3) = S(0) * M(0, 2) + S(1) * M(1, 2) + S(2) * M(2, 2) + M(3, 2)
  194.      * st(2) = S(0) * M(0, 0) + S(1) * M(1, 0) + S(2) * M(2, 0) + M(3, 0)
  195.      * st(1) = S(0) * M(0, 1) + S(1) * M(1, 1) + S(2) * M(2, 1) + M(3, 1)
  196.      * st(0) = S(0) * M(0, 3) + S(1) * M(1, 3) + S(2) * M(2, 3) + M(3, 3)
  197.      */
  198.  
  199.     fxch %st(3)     /* 3 1 2 0 */
  200.     fstps D(2)     /* 1 2 0 */
  201.     fxch %st(1)     /* 2 1 0 */
  202.     fstps D(0)     /* 1 0 */
  203.     leal S(4), %esi
  204.     fstps D(1)     /* 0 */
  205.     decl %ecx
  206.     fstps D(3)     /* */
  207.  
  208.     leal D(4), %edi
  209.  
  210.     jnz 1b
  211.  
  212. 2:    popl %edi
  213.     popl %esi
  214.     ret
  215.  
  216.  
  217. /*
  218.  * void asm_transform_points3_identity( GLuint n, GLfloat d[][4],
  219.  *                                      GLfloat s[][4] );
  220.  */
  221. #ifdef FREEBSD
  222. GLOBAL(_asm_transform_points3_identity)
  223. ALIGN
  224. _asm_transform_points3_identity:
  225. #else
  226. GLOBAL(asm_transform_points3_identity)
  227. ALIGN
  228. asm_transform_points3_identity:
  229. #endif
  230.     pushl %esi
  231.     pushl %edi
  232.     movl 12(%esp), %ecx     /* ecx = n */
  233.     movl 16(%esp), %edi     /* edi = d */
  234.     movl 20(%esp), %esi     /* esi = s */
  235.     pushl %ebx
  236.     pushl %ebp
  237.  
  238.     testl %ecx, %ecx
  239.     jz 2f
  240.  
  241.     movl $0x3f800000, %ebp
  242.  
  243. ALIGN
  244. 1:    movl S(0), %eax
  245.     movl S(1), %edx
  246.     movl S(2), %ebx
  247.     leal S(4), %esi
  248.     movl %eax, D(0)
  249.     movl %edx, D(1)
  250.     movl %ebx, D(2)
  251.     movl %ebp, D(3)
  252.     decl %ecx
  253.     leal D(4), %edi
  254.     jnz 1b
  255.  
  256. 2:    popl %ebp
  257.     popl %ebx
  258.     popl %edi
  259.     popl %esi
  260.     ret
  261.  
  262.  
  263. /*
  264.  * void asm_transform_points3_2d( GLuint n, GLfloat d[][4], GLfloat m[16],
  265.  *                                GLfloat s[][4] );
  266.  */
  267. #ifdef FREEBSD
  268. GLOBAL(_asm_transform_points3_2d)
  269. ALIGN
  270. _asm_transform_points3_2d:
  271. #else
  272. GLOBAL(asm_transform_points3_2d)
  273. ALIGN
  274. asm_transform_points3_2d:
  275. #endif
  276.     pushl %esi
  277.     pushl %edi
  278.     movl 12(%esp), %ecx     /* ecx = n */
  279.     movl 16(%esp), %edi     /* edi = d */
  280.     movl 20(%esp), %edx     /* edx = m */
  281.     movl 24(%esp), %esi     /* esi = s */
  282.     pushl %ebp
  283.  
  284.     movl $0x3f800000, %ebp
  285.  
  286.     testb $1, %cl
  287.     jz 1f
  288.  
  289.     decl %ecx
  290.  
  291.     flds S(0)
  292.     fmuls M(0, 0)
  293.     flds S(0)
  294.     fmuls M(0, 1)
  295.     flds S(1)
  296.     fmuls M(1, 0)
  297.     flds S(1)
  298.     fmuls M(1, 1)
  299.  
  300.     /*
  301.      * st(3) = S(0) * M(0, 0)
  302.      * st(2) = S(0) * M(0, 1)
  303.      * st(1) = S(1) * M(1, 0)
  304.      * st(0) = S(1) * M(1, 1)
  305.      */
  306.  
  307.     fxch %st(1)     /* 1 0 2 3 */
  308.     fadds M(3, 0)
  309.     fxch %st(1)     /* 0 1 2 3 */
  310.     fadds M(3, 1)
  311.     fxch %st(1)     /* 1 0 2 3 */
  312.     faddp %st(3)     /* 0 2 3 */
  313.     faddp %st(1)     /* 2 3 */
  314.     fstps D(1)     /* 3 */
  315.     fstps D(0)     /* */
  316.     movl S(2), %eax
  317.     leal S(4), %esi
  318.     movl %ebp, D(3)
  319.     movl %eax, D(2)
  320.     leal D(4), %edi
  321.  
  322. 1:    testl %ecx, %ecx
  323.     jz 2f
  324.  
  325. ALIGN
  326. 1:    flds S(0)
  327.     fmuls M(0, 0)
  328.     flds S(0)
  329.     fmuls M(0, 1)
  330.     flds S(4)
  331.     fmuls M(0, 0)
  332.     flds S(4)
  333.     fmuls M(0, 1)
  334.     flds S(1)
  335.     fmuls M(1, 0)
  336.     flds S(1)
  337.     fmuls M(1, 1)
  338.     flds S(5)
  339.     fmuls M(1, 0)
  340.     flds S(5)
  341.     fmuls M(1, 1)
  342.  
  343.     /*
  344.      * st(7) = S(0) * M(0, 0)
  345.      * st(6) = S(0) * M(0, 1)
  346.      * st(5) = S(4) * M(0, 0)
  347.      * st(4) = S(4) * M(0, 1)
  348.      * st(3) = S(1) * M(1, 0)
  349.      * st(2) = S(1) * M(1, 1)
  350.      * st(1) = S(5) * M(1, 0)
  351.      * st(0) = S(5) * M(1, 1)
  352.      */
  353.  
  354.     fxch %st(7)     /* 7 1 2 3 4 5 6 0 */
  355.     fadds M(3, 0)
  356.     fxch %st(6)     /* 6 1 2 3 4 5 7 0 */
  357.     fadds M(3, 1)
  358.     fxch %st(5)     /* 5 1 2 3 4 6 7 0 */
  359.     fadds M(3, 0)
  360.     fxch %st(4)     /* 4 1 2 3 5 6 7 0 */
  361.     fadds M(3, 1)
  362.  
  363.     movl S(2), %eax
  364.     movl %ebp, D(3)
  365.     movl %eax, D(2)
  366.     movl S(6), %eax
  367.     movl %ebp, D(7)
  368.     movl %eax, D(6)
  369.     leal S(8), %esi
  370.     subl $2, %ecx
  371.  
  372.     /*
  373.      * st(7) = S(5) * M(1, 1)
  374.      * st(6) = S(0) * M(0, 0) + M(3, 0)
  375.      * st(5) = S(0) * M(0, 1) + M(3, 1)
  376.      * st(4) = S(4) * M(0, 0) + M(3, 0)
  377.      * st(3) = S(1) * M(1, 0)
  378.      * st(2) = S(1) * M(1, 1)
  379.      * st(1) = S(5) * M(1, 0)
  380.      * st(0) = S(4) * M(0, 1) + M(3, 1)
  381.      */
  382.  
  383.     faddp %st(7)     /* 1 2 3 4 5 6 7 */
  384.     faddp %st(3)     /* 2 3 4 5 6 7 */
  385.     faddp %st(3)     /* 3 4 5 6 7 */
  386.     faddp %st(3)     /* 4 5 6 7 */
  387.     fxch %st(3)     /* 7 5 6 4 */
  388.     fstps D(5)     /* 5 6 4 */
  389.     fstps D(1)     /* 6 4 */
  390.     fstps D(0)     /* 4 */
  391.     fstps D(4)     /* */
  392.  
  393.     leal D(8), %edi
  394.     jnz 1b
  395.  
  396. 2:    popl %ebp
  397.     popl %edi
  398.     popl %esi
  399.     ret
  400.  
  401.  
  402. /*
  403.  * void asm_transform_points3_2d_no_rot( GLuint n, GLfloat d[][4],
  404.  *                                       GLfloat m[16], GLfloat s[][4] );
  405.  *
  406.  */
  407. #ifdef FREEBSD
  408. GLOBAL(_asm_transform_points3_2d_no_rot)
  409. ALIGN
  410. _asm_transform_points3_2d_no_rot:
  411. #else
  412. GLOBAL(asm_transform_points3_2d_no_rot)
  413. ALIGN
  414. asm_transform_points3_2d_no_rot:
  415. #endif
  416.     pushl %esi
  417.     pushl %edi
  418.     movl 12(%esp), %ecx     /* ecx = n */
  419.     movl 16(%esp), %edi     /* edi = d */
  420.     movl 20(%esp), %edx     /* edx = m */
  421.     movl 24(%esp), %esi     /* esi = s */
  422.     pushl %ebp
  423.  
  424.     testl %ecx, %ecx
  425.     jz 2f
  426.  
  427.     movl $0x3f800000, %ebp
  428.  
  429. ALIGN
  430. 1:    flds S(0)
  431.     fmuls M(0, 0)
  432.     flds S(1)
  433.     fmuls M(1, 1)
  434.     fxch %st(1)
  435.     fadds M(3, 0)
  436.     fxch %st(1)
  437.     fadds M(3, 1)
  438.     fxch %st(1)
  439.     fstps D(0)
  440.     fstps D(1)
  441.  
  442.     movl S(2), %eax   /* cycle 1: U pipe */
  443.     movl %ebp, D(3)   /*          V pipe */
  444.     movl %eax, D(2)   /* cycle 2: U pipe */
  445.  
  446.     decl %ecx
  447.     leal S(4), %esi
  448.     leal D(4), %edi
  449.     jnz 1b
  450.  
  451. 2:    popl %ebp
  452.     popl %edi
  453.     popl %esi
  454.     ret
  455.  
  456.  
  457.  
  458. /*
  459.  * void asm_transform_points3_3d( GLuint n, GLfloat d[][4], GLfloat m[16],
  460.  *                                GLfloat s[][4] );
  461.  */
  462. #ifdef FREEBSD
  463. GLOBAL(_asm_transform_points3_3d)
  464. ALIGN
  465. _asm_transform_points3_3d:
  466. #else
  467. GLOBAL(asm_transform_points3_3d)
  468. ALIGN
  469. asm_transform_points3_3d:
  470. #endif
  471.     pushl %esi
  472.     pushl %edi
  473.     movl 12(%esp), %ecx     /* ecx = n */
  474.     movl 16(%esp), %edi     /* edi = d */
  475.     movl 20(%esp), %edx     /* edx = m */
  476.     movl 24(%esp), %esi     /* esi = s */
  477.  
  478.     testl %ecx, %ecx
  479.     jz 2f
  480.  
  481.     movl $0x3f800000, %eax
  482.  
  483. ALIGN
  484. 1:    flds S(0)
  485.     fmuls M(0, 0)
  486.     flds S(0)
  487.     fmuls M(0, 1)
  488.     flds S(0)
  489.     fmuls M(0, 2)
  490.  
  491.     flds S(1)
  492.     fmuls M(1, 0)
  493.     flds S(1)
  494.     fmuls M(1, 1)
  495.     flds S(1)
  496.     fmuls M(1, 2)
  497.  
  498.     /*
  499.      * st(5) = S(0) * M(0, 0)
  500.      * st(4) = S(0) * M(0, 1)
  501.      * st(3) = S(0) * M(0, 2)
  502.      * st(2) = S(1) * M(1, 0)
  503.      * st(1) = S(1) * M(1, 1)
  504.      * st(0) = S(1) * M(1, 2)
  505.      */
  506.  
  507.     fxch %st(2)         /* 2 1 0 3 4 5 */
  508.     faddp %st, %st(5)     /* 1 0 3 4 5 */
  509.     faddp %st, %st(3)     /* 0 3 4 5 */
  510.     faddp %st, %st(1)     /* 3 4 5 */
  511.  
  512.     /*
  513.      * st(2) = S(0) * M(0, 0) + S(1) * M(1, 0)
  514.      * st(1) = S(0) * M(0, 1) + S(1) * M(1, 1)
  515.      * st(0) = S(0) * M(0, 2) + S(1) * M(1, 2)
  516.      */
  517.  
  518.     flds S(2)
  519.     fmuls M(2, 0)
  520.     flds S(2)
  521.     fmuls M(2, 1)
  522.     flds S(2)
  523.     fmuls M(2, 2)
  524.  
  525.     /*
  526.      * st(5) = S(0) * M(0, 0) + S(1) * M(1, 0)
  527.      * st(4) = S(0) * M(0, 1) + S(1) * M(1, 1)
  528.      * st(3) = S(0) * M(0, 2) + S(1) * M(1, 2)
  529.      * st(2) = S(2) * M(2, 0)
  530.      * st(1) = S(2) * M(2, 1)
  531.      * st(0) = S(2) * M(2, 2)
  532.      */
  533.  
  534.     fxch %st(2)         /* 2 1 0 3 4 5 */
  535.     faddp %st, %st(5)     /* 1 0 3 4 5 */
  536.     faddp %st, %st(3)     /* 0 3 4 5 */
  537.     faddp %st, %st(1)     /* 3 4 5 */
  538.  
  539.     /*
  540.      * st(2) = S(0) * M(0, 0) + S(1) * M(1, 0) + S(2) * M(2, 0)
  541.      * st(1) = S(0) * M(0, 1) + S(1) * M(1, 1) + S(2) * M(2, 1)
  542.      * st(0) = S(0) * M(0, 2) + S(1) * M(1, 2) + S(2) * M(2, 2)
  543.      */
  544.  
  545.     fxch %st(2)     /* 2 1 0 */
  546.     fadds M(3, 0)
  547.     fxch %st(1)     /* 1 2 0 */
  548.     fadds M(3, 1)
  549.     fxch %st(2)     /* 0 2 1 */
  550.     fadds M(3, 2)
  551.  
  552.     fxch %st(1)     /* 2 0 1 */
  553.     fstps D(0)     /* 0 1 */
  554.     fstps D(2)     /* 1 */
  555.     fstps D(1)     /* */
  556.     movl %eax, D(3)
  557.  
  558.     leal S(4), %esi
  559.     decl %ecx
  560.  
  561.     leal D(4), %edi
  562.  
  563.     jnz 1b
  564.  
  565. 2:    popl %edi
  566.     popl %esi
  567.     ret
  568.  
  569.  
  570.  
  571. /*
  572.  * void asm_transform_points4_general( GLuint n, GLfloat d[][4],
  573.  *                                     GLfloat m[16], GLfloat s[][4] );
  574.  */
  575. #ifdef FREEBSD
  576. GLOBAL(_asm_transform_points4_general)
  577. ALIGN
  578. _asm_transform_points4_general:
  579. #else
  580. GLOBAL(asm_transform_points4_general)
  581. ALIGN
  582. asm_transform_points4_general:
  583. #endif
  584.     pushl %esi
  585.     pushl %edi
  586.     movl 12(%esp), %ecx     /* ecx = n */
  587.     movl 16(%esp), %edi     /* edi = d */
  588.     movl 20(%esp), %edx     /* edx = m */
  589.     movl 24(%esp), %esi     /* esi = s */
  590.  
  591.     testl %ecx, %ecx
  592.     jz 2f
  593.  
  594. ALIGN
  595. 1:    flds S(0)
  596.     fmuls M(0, 0)
  597.     flds S(0)
  598.     fmuls M(0, 1)
  599.     flds S(0)
  600.     fmuls M(0, 2)
  601.     flds S(0)
  602.     fmuls M(0, 3)
  603.  
  604.     flds S(1)
  605.     fmuls M(1, 0)
  606.     flds S(1)
  607.     fmuls M(1, 1)
  608.     flds S(1)
  609.     fmuls M(1, 2)
  610.     flds S(1)
  611.     fmuls M(1, 3)
  612.  
  613.     /*
  614.      * st(7) = S(0) * M(0, 0)
  615.      * st(6) = S(0) * M(0, 1)
  616.      * st(5) = S(0) * M(0, 2)
  617.      * st(4) = S(0) * M(0, 3)
  618.      * st(3) = S(1) * M(1, 0)
  619.      * st(2) = S(1) * M(1, 1)
  620.      * st(1) = S(1) * M(1, 2)
  621.      * st(0) = S(1) * M(1, 3)
  622.      */
  623.  
  624.     fxch %st(3)        /* 3 1 2 0 4 5 6 7 */
  625.     faddp %st, %st(7)     /* 1 2 0 4 5 6 7 */
  626.     fxch %st(1)        /* 2 1 0 4 5 6 7 */
  627.     faddp %st, %st(5)     /* 1 0 4 5 6 7 */
  628.     faddp %st, %st(3)     /* 0 4 5 6 7 */
  629.     faddp %st, %st(1)     /* 4 5 6 7 */
  630.  
  631.     /*
  632.      * st(3) = S(0) * M(0, 0) + S(1) * M(1, 0)
  633.      * st(2) = S(0) * M(0, 1) + S(1) * M(1, 1)
  634.      * st(1) = S(0) * M(0, 2) + S(1) * M(1, 2)
  635.      * st(0) = S(0) * M(0, 3) + S(1) * M(1, 3)
  636.      */
  637.  
  638.     flds S(2)
  639.     fmuls M(2, 0)
  640.     flds S(2)
  641.     fmuls M(2, 1)
  642.     flds S(2)
  643.     fmuls M(2, 2)
  644.     flds S(2)
  645.     fmuls M(2, 3)
  646.  
  647.     /*
  648.      * st(7) = S(0) * M(0, 0) + S(1) * M(1, 0)
  649.      * st(6) = S(0) * M(0, 1) + S(1) * M(1, 1)
  650.      * st(5) = S(0) * M(0, 2) + S(1) * M(1, 2)
  651.      * st(4) = S(0) * M(0, 3) + S(1) * M(1, 3)
  652.      * st(3) = S(2) * M(2, 0)
  653.      * st(2) = S(2) * M(2, 1)
  654.      * st(1) = S(2) * M(2, 2)
  655.      * st(0) = S(2) * M(2, 3)
  656.      */
  657.  
  658.     fxch %st(3)        /* 3 1 2 0 4 5 6 7 */
  659.     faddp %st, %st(7)     /* 1 2 0 4 5 6 7 */
  660.     fxch %st(1)        /* 2 1 0 4 5 6 7 */
  661.     faddp %st, %st(5)     /* 1 0 4 5 6 7 */
  662.     faddp %st, %st(3)     /* 0 4 5 6 7 */
  663.     faddp %st, %st(1)     /* 4 5 6 7 */
  664.  
  665.     /*
  666.      * st(3) = S(0) * M(0, 0) + S(1) * M(1, 0) + S(2) * M(2, 0)
  667.      * st(2) = S(0) * M(0, 1) + S(1) * M(1, 1) + S(2) * M(2, 1)
  668.      * st(1) = S(0) * M(0, 2) + S(1) * M(1, 2) + S(2) * M(2, 2)
  669.      * st(0) = S(0) * M(0, 3) + S(1) * M(1, 3) + S(2) * M(2, 3)
  670.      */
  671.  
  672.     flds S(3)
  673.     fmuls M(3, 0)
  674.     flds S(3)
  675.     fmuls M(3, 1)
  676.     flds S(3)
  677.     fmuls M(3, 2)
  678.     flds S(3)
  679.     fmuls M(3, 3)
  680.  
  681.     /*
  682.      * st(7) = S(0) * M(0, 0) + S(1) * M(1, 0) + S(2) * M(2, 0)
  683.      * st(6) = S(0) * M(0, 1) + S(1) * M(1, 1) + S(2) * M(2, 1)
  684.      * st(5) = S(0) * M(0, 2) + S(1) * M(1, 2) + S(2) * M(2, 2)
  685.      * st(4) = S(0) * M(0, 3) + S(1) * M(1, 3) + S(2) * M(2, 3)
  686.      * st(3) = S(3) * M(3, 0)
  687.      * st(2) = S(3) * M(3, 1)
  688.      * st(1) = S(3) * M(3, 2)
  689.      * st(0) = S(3) * M(3, 3)
  690.      */
  691.  
  692.     fxch %st(3)        /* 3 1 2 0 4 5 6 7 */
  693.     faddp %st, %st(7)     /* 1 2 0 4 5 6 7 */
  694.     fxch %st(1)        /* 2 1 0 4 5 6 7 */
  695.     faddp %st, %st(5)     /* 1 0 4 5 6 7 */
  696.     faddp %st, %st(3)     /* 0 4 5 6 7 */
  697.  
  698.     leal S(4), %esi
  699.     decl %ecx
  700.  
  701.     faddp %st, %st(1)     /* 4 5 6 7 */
  702.  
  703.     /*
  704.      * st(3) = S(0) * M(0, 0) + S(1) * M(1, 0) + S(2) * M(2, 0) + S(3) * M(3, 0)
  705.      * st(2) = S(0) * M(0, 1) + S(1) * M(1, 1) + S(2) * M(2, 1) + S(3) * M(3, 1)
  706.      * st(1) = S(0) * M(0, 2) + S(1) * M(1, 2) + S(2) * M(2, 2) + S(3) * M(3, 2)
  707.      * st(0) = S(0) * M(0, 3) + S(1) * M(1, 3) + S(2) * M(2, 3) + S(3) * M(3, 3)
  708.      */
  709.  
  710.     fxch %st(3)     /* 3 1 2 0 */
  711.     fstps D(0)     /* 1 2 0 */
  712.     fxch %st(1)     /* 2 1 0 */
  713.     fstps D(1)     /* 1 0 */
  714.     fstps D(2)     /* 0 */
  715.     fstps D(3)     /* */
  716.  
  717.     leal D(4), %edi
  718.  
  719.     jnz 1b
  720.  
  721. 2:    popl %edi
  722.     popl %esi
  723.     ret
  724.  
  725.  
  726.  
  727. /*
  728.  * void asm_transform_points4_identity( GLuint n, GLfloat d[][4],
  729.  *                                      GLfloat s[][4] );
  730.  */
  731. #ifdef FREEBSD
  732. GLOBAL(_asm_transform_points4_identity)
  733. ALIGN
  734. _asm_transform_points4_identity:
  735. #else
  736. GLOBAL(asm_transform_points4_identity)
  737. ALIGN
  738. asm_transform_points4_identity:
  739. #endif
  740.     pushl %esi
  741.     pushl %edi
  742.     movl 12(%esp), %ecx     /* ecx = n */
  743.     movl 16(%esp), %edi     /* edi = d */
  744.     movl 20(%esp), %esi     /* esi = s */
  745.  
  746.     leal (, %ecx, 4), %ecx
  747.  
  748.     cld
  749.     rep; movsl
  750.  
  751.     popl %edi
  752.     popl %esi
  753.     ret
  754.  
  755.  
  756.  
  757. /*
  758.  * void asm_transform_points4_2d( GLuint n, GLfloat d[][4], GLfloat m[16],
  759.  *                                GLfloat s[][4] );
  760.  */
  761. #ifdef FREEBSD
  762. GLOBAL(_asm_transform_points4_2d)
  763. ALIGN
  764. _asm_transform_points4_2d:
  765. #else
  766. GLOBAL(asm_transform_points4_2d)
  767. ALIGN
  768. asm_transform_points4_2d:
  769. #endif
  770.     pushl %esi
  771.     pushl %edi
  772.     movl 12(%esp), %ecx     /* ecx = n */
  773.     movl 16(%esp), %edi     /* edi = d */
  774.     movl 20(%esp), %edx     /* edx = m */
  775.     movl 24(%esp), %esi     /* esi = s */
  776.  
  777.     testl %ecx, %ecx
  778.     jz 2f
  779.  
  780.     pushl %ebx
  781.  
  782. ALIGN
  783. 1:    flds S(0)
  784.     fmuls M(0, 0)
  785.     flds S(0)
  786.     fmuls M(0, 1)
  787.     flds S(1)
  788.     fmuls M(1, 0)
  789.     flds S(1)
  790.     fmuls M(1, 1)
  791.     flds S(3)
  792.     fmuls M(3, 0)
  793.     flds S(3)
  794.     fmuls M(3, 1)
  795.  
  796.     /*
  797.      * st(5) = S(0) * M(0, 0)
  798.      * st(4) = S(0) * M(0, 1)
  799.      * st(3) = S(1) * M(1, 0)
  800.      * st(2) = S(1) * M(1, 1)
  801.      * st(1) = S(3) * M(3, 0)
  802.      * st(0) = S(3) * M(3, 1)
  803.      */
  804.  
  805.     movl S(2), %eax
  806.     movl S(3), %ebx
  807.     leal S(4), %esi
  808.     decl %ecx
  809.     movl %eax, D(2)
  810.     movl %ebx, D(3)
  811.     faddp %st(4)
  812.     faddp %st(4)
  813.     faddp %st(2)
  814.     faddp %st(2)
  815.     fstps D(1)
  816.     fstps D(0)
  817.     leal D(4), %edi
  818.     jnz 1b
  819.  
  820.     popl %ebx
  821.  
  822. 2:    popl %edi
  823.     popl %esi
  824.     ret
  825.  
  826.  
  827.  
  828. /*
  829.  * void asm_transform_points4_2d_no_rot( GLuint n, GLfloat d[][4],
  830.  *                                       GLfloat m[16], GLfloat s[][4] );
  831.  */
  832. #ifdef FREEBSD
  833. GLOBAL(_asm_transform_points4_2d_no_rot)
  834. ALIGN
  835. _asm_transform_points4_2d_no_rot:
  836. #else
  837. GLOBAL(asm_transform_points4_2d_no_rot)
  838. ALIGN
  839. asm_transform_points4_2d_no_rot:
  840. #endif
  841.     pushl %esi
  842.     pushl %edi
  843.     movl 12(%esp), %ecx     /* ecx = n */
  844.     movl 16(%esp), %edi     /* edi = d */
  845.     movl 20(%esp), %edx     /* edx = m */
  846.     movl 24(%esp), %esi     /* esi = s */
  847.  
  848.     testl %ecx, %ecx
  849.     jz 2f
  850.     pushl %ebx
  851.  
  852. ALIGN
  853. 1:    flds S(0)
  854.     fmuls M(0, 0)
  855.     flds S(1)
  856.     fmuls M(1, 1)
  857.     flds S(3)
  858.     fmuls M(3, 0)
  859.     flds S(3)
  860.     fmuls M(3, 1)
  861.     movl S(2), %eax
  862.     movl S(3), %ebx
  863.     leal S(4), %esi
  864.     decl %ecx
  865.     movl %eax, D(2)
  866.     movl %ebx, D(3)
  867.     faddp %st(2)
  868.     faddp %st(2)
  869.     fstps D(1)
  870.     fstps D(0)
  871.     leal D(4), %edi
  872.     jnz 1b
  873.  
  874.     popl %ebx
  875.  
  876. 2:    popl %edi
  877.     popl %esi
  878.     ret
  879.  
  880.  
  881.  
  882. /*
  883.  * void asm_transform_points4_3d( GLuint n, GLfloat d[][4], GLfloat m[16],
  884.  *                                GLfloat s[][4] );
  885.  */
  886. #ifdef FREEBSD
  887. GLOBAL(_asm_transform_points4_3d)
  888. ALIGN
  889. _asm_transform_points4_3d:
  890. #else
  891. GLOBAL(asm_transform_points4_3d)
  892. ALIGN
  893. asm_transform_points4_3d:
  894. #endif
  895.     pushl %esi
  896.     pushl %edi
  897.     movl 12(%esp), %ecx     /* ecx = n */
  898.     movl 16(%esp), %edi     /* edi = d */
  899.     movl 20(%esp), %edx     /* edx = m */
  900.     movl 24(%esp), %esi     /* esi = s */
  901.  
  902.     testl %ecx, %ecx
  903.     jz 2f
  904.  
  905. ALIGN
  906. 1:    flds S(3)
  907.  
  908.     flds S(0)
  909.     fmuls M(0, 0)
  910.     flds S(0)
  911.     fmuls M(0, 1)
  912.     flds S(0)
  913.     fmuls M(0, 2)
  914.  
  915.     flds S(1)
  916.     fmuls M(1, 0)
  917.     flds S(1)
  918.     fmuls M(1, 1)
  919.     flds S(1)
  920.     fmuls M(1, 2)
  921.  
  922.     /*
  923.      * st(5) = S(0) * M(0, 0)
  924.      * st(4) = S(0) * M(0, 1)
  925.      * st(3) = S(0) * M(0, 2)
  926.      * st(2) = S(1) * M(1, 0)
  927.      * st(1) = S(1) * M(1, 1)
  928.      * st(0) = S(1) * M(1, 2)
  929.      */
  930.  
  931.     fxch %st(2)         /* 2 1 0 3 4 5 */
  932.     faddp %st, %st(5)     /* 1 0 3 4 5 */
  933.     faddp %st, %st(3)     /* 0 3 4 5 */
  934.     faddp %st, %st(1)     /* 3 4 5 */
  935.  
  936.     /*
  937.      * st(2) = S(0) * M(0, 0) + S(1) * M(1, 0)
  938.      * st(1) = S(0) * M(0, 1) + S(1) * M(1, 1)
  939.      * st(0) = S(0) * M(0, 2) + S(1) * M(1, 2)
  940.      */
  941.  
  942.     flds S(2)
  943.     fmuls M(2, 0)
  944.     flds S(2)
  945.     fmuls M(2, 1)
  946.     flds S(2)
  947.     fmuls M(2, 2)
  948.  
  949.     /*
  950.      * st(5) = S(0) * M(0, 0) + S(1) * M(1, 0)
  951.      * st(4) = S(0) * M(0, 1) + S(1) * M(1, 1)
  952.      * st(3) = S(0) * M(0, 2) + S(1) * M(1, 2)
  953.      * st(2) = S(2) * M(2, 0)
  954.      * st(1) = S(2) * M(2, 1)
  955.      * st(0) = S(2) * M(2, 2)
  956.      */
  957.  
  958.     fxch %st(2)         /* 2 1 0 3 4 5 */
  959.     faddp %st, %st(5)     /* 1 0 3 4 5 */
  960.     faddp %st, %st(3)     /* 0 3 4 5 */
  961.     faddp %st, %st(1)     /* 3 4 5 */
  962.  
  963.     /*
  964.      * st(2) = S(0) * M(0, 0) + S(1) * M(1, 0) + S(2) * M(2, 0)
  965.      * st(1) = S(0) * M(0, 1) + S(1) * M(1, 1) + S(2) * M(2, 1)
  966.      * st(0) = S(0) * M(0, 2) + S(1) * M(1, 2) + S(2) * M(2, 2)
  967.      */
  968.  
  969.     flds S(3)
  970.     fmuls M(3, 0)
  971.     flds S(3)
  972.     fmuls M(3, 1)
  973.     flds S(3)
  974.     fmuls M(3, 2)
  975.  
  976.     /*
  977.      * st(5) = S(0) * M(0, 0) + S(1) * M(1, 0) + S(2) * M(2, 0)
  978.      * st(4) = S(0) * M(0, 1) + S(1) * M(1, 1) + S(2) * M(2, 1)
  979.      * st(3) = S(0) * M(0, 2) + S(1) * M(1, 2) + S(2) * M(2, 2)
  980.      * st(2) = S(3) * M(3, 0)
  981.      * st(1) = S(3) * M(3, 1)
  982.      * st(0) = S(3) * M(3, 2)
  983.      */
  984.  
  985.     fxch %st(2)         /* 2 1 0 3 4 5 */
  986.     faddp %st, %st(5)     /* 1 0 3 4 5 */
  987.     faddp %st, %st(3)     /* 0 3 4 5 */
  988.  
  989.     leal S(4), %esi
  990.     decl %ecx
  991.  
  992.     faddp %st, %st(1)     /* 3 4 5 */
  993.  
  994.     /*
  995.      * st(2) = S(0) * M(0, 0) + S(1) * M(1, 0) + S(2) * M(2, 0) + S(3) * M(3, 0)
  996.      * st(1) = S(0) * M(0, 1) + S(1) * M(1, 1) + S(2) * M(2, 1) + S(3) * M(3, 1)
  997.      * st(0) = S(0) * M(0, 2) + S(1) * M(1, 2) + S(2) * M(2, 2) + S(3) * M(3, 2)
  998.      */
  999.  
  1000.     fxch %st(2)     /* 2 1 0 */
  1001.     fstps D(0)     /* 1 0 */
  1002.     fstps D(1)     /* 0 */
  1003.     fstps D(2)     /* */
  1004.     fstps D(3)
  1005.  
  1006.     leal D(4), %edi
  1007.  
  1008.     jnz 1b
  1009.  
  1010. 2:    popl %edi
  1011.     popl %esi
  1012.     ret
  1013.  
  1014. /*
  1015.  * void asm_transform_points4_ortho( GLuint n, GLfloat d[][4],
  1016.  *                                   GLfloat m[16], GLfloat s[][4] );
  1017.  */
  1018. #ifdef FREEBSD
  1019. GLOBAL(_asm_transform_points4_ortho)
  1020. ALIGN
  1021. _asm_transform_points4_ortho:
  1022. #else
  1023. GLOBAL(asm_transform_points4_ortho)
  1024. ALIGN
  1025. asm_transform_points4_ortho:
  1026. #endif
  1027.     pushl %esi
  1028.     pushl %edi
  1029.     movl 12(%esp), %ecx     /* ecx = n */
  1030.     movl 16(%esp), %edi     /* edi = d */
  1031.     movl 20(%esp), %edx     /* edx = m */
  1032.     movl 24(%esp), %esi     /* esi = s */
  1033.  
  1034.     testl %ecx, %ecx
  1035.     jz 2f
  1036.  
  1037. ALIGN
  1038. 1:    flds S(0)
  1039.     fmuls M(0, 0)
  1040.     flds S(1)
  1041.     fmuls M(1, 1)
  1042.     flds S(2)
  1043.     fmuls M(2, 2)
  1044.  
  1045.     flds S(3)
  1046.     fmuls M(3, 0)
  1047.     flds S(3)
  1048.     fmuls M(3, 1)
  1049.     flds S(3)
  1050.     fmuls M(3, 2)
  1051.  
  1052.     movl S(3), %eax
  1053.     leal S(4), %esi
  1054.     decl %ecx
  1055.     movl %eax, D(3)
  1056.  
  1057.     faddp %st(3)
  1058.     faddp %st(3)
  1059.     faddp %st(3)
  1060.  
  1061.     fstps D(2)
  1062.     fstps D(1)
  1063.     fstps D(0)
  1064.  
  1065.     leal D(4), %edi
  1066.     jnz 1b
  1067.  
  1068. 2:    popl %edi
  1069.     popl %esi
  1070.     ret
  1071.  
  1072. /*
  1073.  * void asm_transform_points4_perspective( GLuint n, GLfloat d[][4],
  1074.  *                                         GLfloat m[16], GLfloat s[][4] );
  1075.  */
  1076. #ifdef FREEBSD
  1077. GLOBAL(_asm_transform_points4_perspective)
  1078. ALIGN
  1079. _asm_transform_points4_perspective:
  1080. #else
  1081. GLOBAL(asm_transform_points4_perspective)
  1082. ALIGN
  1083. asm_transform_points4_perspective:
  1084. #endif
  1085.     pushl %esi
  1086.     pushl %edi
  1087.     movl 12(%esp), %ecx     /* ecx = n */
  1088.     movl 16(%esp), %edi     /* edi = d */
  1089.     movl 20(%esp), %edx     /* edx = m */
  1090.     movl 24(%esp), %esi     /* esi = s */
  1091.  
  1092.     testl %ecx, %ecx
  1093.     jz 2f
  1094.  
  1095. ALIGN
  1096. 1:    flds S(0)
  1097.     fmuls M(0, 0)
  1098.     flds S(1)
  1099.     fmuls M(1, 1)
  1100.     flds S(2)
  1101.     fmuls M(2, 2)
  1102.  
  1103.     flds S(2)
  1104.     fmuls M(2, 0)
  1105.     flds S(2)
  1106.     fmuls M(2, 1)
  1107.     flds S(3)
  1108.     fmuls M(3, 2)
  1109.  
  1110.     movl S(2), %eax
  1111.     leal S(4), %esi
  1112.     xorl $0x80000000, %eax
  1113.     decl %ecx
  1114.  
  1115.     faddp %st(3)
  1116.     faddp %st(3)
  1117.     faddp %st(3)
  1118.  
  1119.     fstps D(2)
  1120.     fstps D(1)
  1121.     fstps D(0)
  1122.  
  1123.     movl %eax, D(3)
  1124.     leal D(4), %edi
  1125.     jnz 1b
  1126.  
  1127. 2:    popl %edi
  1128.     popl %esi
  1129.     ret
  1130.  
  1131.  
  1132.  
  1133. /*
  1134.  * Table for clip test.
  1135.  *
  1136.  *     bit6 = S(3) < 0
  1137.  *     bit5 = S(2) < 0
  1138.  *     bit4 = abs(S(2)) > abs(S(3))
  1139.  *     bit3 = S(1) < 0
  1140.  *     bit2 = abs(S(1)) > abs(S(3))
  1141.  *     bit1 = S(0) < 0
  1142.  *     bit0 = abs(S(0)) > abs(S(3))
  1143.  */
  1144.  
  1145. /* Vertex buffer clipping flags (from vb.h) */
  1146. #define CLIP_RIGHT_BIT   0x01
  1147. #define CLIP_LEFT_BIT    0x02
  1148. #define CLIP_TOP_BIT     0x04
  1149. #define CLIP_BOTTOM_BIT  0x08
  1150. #define CLIP_NEAR_BIT    0x10
  1151. #define CLIP_FAR_BIT     0x20
  1152. #define CLIP_USER_BIT    0x40
  1153. #define CLIP_ALL_BITS    0x3f
  1154.  
  1155. #define MAGN_X(i)     (~(((i) & 1) - 1))
  1156. #define SIGN_X(i)     (~((((i) >> 1) & 1) - 1))
  1157. #define MAGN_Y(i)     (~((((i) >> 2) & 1) - 1))
  1158. #define SIGN_Y(i)     (~((((i) >> 3) & 1) - 1))
  1159. #define MAGN_Z(i)     (~((((i) >> 4) & 1) - 1))
  1160. #define SIGN_Z(i)     (~((((i) >> 5) & 1) - 1))
  1161. #define SIGN_W(i)     (~((((i) >> 6) & 1) - 1))
  1162.  
  1163. #define CLIP_VALUE(i)                         \
  1164.      (CLIP_RIGHT_BIT                     \
  1165.       & ((~SIGN_X(i) & SIGN_W(i))                 \
  1166.          | (~SIGN_X(i) & ~SIGN_W(i) & MAGN_X(i))         \
  1167.          | (SIGN_X(i) & SIGN_W(i) & ~MAGN_X(i))))         \
  1168.      | (CLIP_LEFT_BIT                     \
  1169.         & ((SIGN_X(i) & SIGN_W(i))                 \
  1170.            | (~SIGN_X(i) & SIGN_W(i) & ~MAGN_X(i))         \
  1171.            | (SIGN_X(i) & ~SIGN_W(i) & MAGN_X(i))))     \
  1172.      | (CLIP_TOP_BIT                     \
  1173.         & ((~SIGN_Y(i) & SIGN_W(i))             \
  1174.            | (~SIGN_Y(i) & ~SIGN_W(i) & MAGN_Y(i))         \
  1175.            | (SIGN_Y(i) & SIGN_W(i) & ~MAGN_Y(i))))     \
  1176.      | (CLIP_BOTTOM_BIT                     \
  1177.         & ((SIGN_Y(i) & SIGN_W(i))                 \
  1178.            | (~SIGN_Y(i) & SIGN_W(i) & ~MAGN_Y(i))         \
  1179.            | (SIGN_Y(i) & ~SIGN_W(i) & MAGN_Y(i))))     \
  1180.      | (CLIP_FAR_BIT                     \
  1181.         & ((~SIGN_Z(i) & SIGN_W(i))             \
  1182.            | (~SIGN_Z(i) & ~SIGN_W(i) & MAGN_Z(i))         \
  1183.            | (SIGN_Z(i) & SIGN_W(i) & ~MAGN_Z(i))))     \
  1184.      | (CLIP_NEAR_BIT                     \
  1185.         & ((SIGN_Z(i) & SIGN_W(i))                 \
  1186.            | (~SIGN_Z(i) & SIGN_W(i) & ~MAGN_Z(i))         \
  1187.            | (SIGN_Z(i) & ~SIGN_W(i) & MAGN_Z(i))))
  1188.  
  1189. #define CLIP_VALUE8(i) \
  1190.     CLIP_VALUE(i + 0), CLIP_VALUE(i + 1), CLIP_VALUE(i + 2), CLIP_VALUE(i + 3), \
  1191.     CLIP_VALUE(i + 4), CLIP_VALUE(i + 5), CLIP_VALUE(i + 6), CLIP_VALUE(i + 7)
  1192.  
  1193. RODATA
  1194.  
  1195. clip_table:
  1196.     .byte CLIP_VALUE8(0x00)
  1197.     .byte CLIP_VALUE8(0x08)
  1198.     .byte CLIP_VALUE8(0x10)
  1199.     .byte CLIP_VALUE8(0x18)
  1200.     .byte CLIP_VALUE8(0x20)
  1201.     .byte CLIP_VALUE8(0x28)
  1202.     .byte CLIP_VALUE8(0x30)
  1203.     .byte CLIP_VALUE8(0x38)
  1204.     .byte CLIP_VALUE8(0x40)
  1205.     .byte CLIP_VALUE8(0x48)
  1206.     .byte CLIP_VALUE8(0x50)
  1207.     .byte CLIP_VALUE8(0x58)
  1208.     .byte CLIP_VALUE8(0x60)
  1209.     .byte CLIP_VALUE8(0x68)
  1210.     .byte CLIP_VALUE8(0x70)
  1211.     .byte CLIP_VALUE8(0x78)
  1212.  
  1213. TEXT
  1214.  
  1215. /*
  1216.  * cliptest -
  1217.  *
  1218.  * inputs:
  1219.  *     ecx = # points
  1220.  *     esi = points
  1221.  *     edi = clipmask[]
  1222.  *
  1223.  * inputs/outputs:
  1224.  *     al = ormask
  1225.  *     ah = andmask
  1226.  */
  1227.  
  1228. cliptest:
  1229.     testl %ecx, %ecx
  1230.     jz 2f
  1231.  
  1232.     pushl %ebp
  1233.     pushl %ebx
  1234.  
  1235. #if defined(__ELF__) && defined(__PIC__)
  1236.     /* store pointer to clip_table on stack */
  1237.     call 3f
  1238.     addl $_GLOBAL_OFFSET_TABLE_, %ebx
  1239.     movl clip_table@GOT(%ebx), %ebx
  1240.     pushl %ebx
  1241.     jmp 1f
  1242.  
  1243. 3:    /* store eip in ebx */
  1244.     movl (%esp), %ebx
  1245.     ret
  1246. #endif
  1247.  
  1248. ALIGN
  1249. 1:    movl S(3), %ebp
  1250.     movl S(2), %ebx
  1251.  
  1252.     xorl %edx, %edx
  1253.     addl %ebp, %ebp    /* %ebp = abs(S(3))*2 ; carry = sign of S(3) */
  1254.  
  1255.     adcl %edx, %edx
  1256.     addl %ebx, %ebx    /* %ebx = abs(S(2))*2 ; carry = sign of S(2) */
  1257.  
  1258.     adcl %edx, %edx
  1259.     cmpl %ebx, %ebp    /* carry = abs(S(2))*2 > abs(S(3))*2 */
  1260.  
  1261.     adcl %edx, %edx
  1262.     movl S(1), %ebx
  1263.  
  1264.     addl %ebx, %ebx    /* %ebx = abs(S(1))*2 ; carry = sign of S(1) */
  1265.  
  1266.     adcl %edx, %edx
  1267.     cmpl %ebx, %ebp    /* carry = abs(S(1))*2 > abs(S(3))*2 */
  1268.  
  1269.     adcl %edx, %edx
  1270.     movl S(0), %ebx
  1271.  
  1272.     addl %ebx, %ebx    /* %ebx = abs(S(0))*2 ; carry = sign of S(0) */
  1273.  
  1274.     adcl %edx, %edx
  1275.     cmpl %ebx, %ebp    /* carry = abs(S(0))*2 > abs(S(3))*2 */
  1276.  
  1277.     adcl %edx, %edx
  1278.  
  1279. #if defined(__ELF__) && defined(__PIC__)
  1280.     movl (%esp), %ebp
  1281.  
  1282.     leal S(4), %esi
  1283.     movb (%edi), %bl
  1284.  
  1285.     movb (%ebp, %edx, 1), %dl
  1286. #else
  1287.     leal S(4), %esi
  1288.  
  1289.     movb (%edi), %bl
  1290.     movb clip_table(%edx), %dl
  1291. #endif
  1292.  
  1293.     orb %dl, %bl
  1294.     orb %dl, %al
  1295.  
  1296.     andb %dl, %ah
  1297.     movb %bl, (%edi)
  1298.  
  1299.     incl %edi
  1300.     decl %ecx
  1301.  
  1302.     jnz 1b
  1303.  
  1304. #if defined(__ELF__) && defined(__PIC__)
  1305.     addl $4, %esp
  1306. #endif
  1307.     popl %ebx
  1308.     popl %ebp
  1309. 2:    ret
  1310.  
  1311. /*
  1312.  * void asm_project_and_cliptest_general( GLuint n, GLfloat d[][4], GLfloat m[16],
  1313.  *                                        GLfloat s[][4], GLubyte clipmask[],
  1314.  *                                        GLubyte *ormask, GLubyte *andmask );
  1315.  */
  1316. #ifdef FREEBSD
  1317. GLOBAL(_asm_project_and_cliptest_general)
  1318. ALIGN
  1319. _asm_project_and_cliptest_general:
  1320. #else
  1321. GLOBAL(asm_project_and_cliptest_general)
  1322. ALIGN
  1323. asm_project_and_cliptest_general:
  1324. #endif
  1325.     pushl %esi
  1326.     pushl %edi
  1327.     movl 12(%esp), %ecx     /* ecx = n */
  1328.     movl 16(%esp), %edi     /* edi = d */
  1329.     movl 20(%esp), %edx     /* edx = m */
  1330.     movl 24(%esp), %esi     /* esi = s */
  1331.  
  1332.     pushl %esi
  1333.     pushl %edx
  1334.     pushl %edi
  1335.     pushl %ecx
  1336. #ifdef FREEBSD
  1337.     call _asm_transform_points4_general
  1338. #else
  1339.     call asm_transform_points4_general
  1340. #endif
  1341.     addl $16, %esp
  1342.  
  1343.     movl 32(%esp), %edi     /* ormask */
  1344.     movl 36(%esp), %esi     /* andmask */
  1345.     movb (%edi), %al
  1346.     movb (%esi), %ah
  1347.  
  1348.     movl 12(%esp), %ecx     /* ecx = n */
  1349.     movl 28(%esp), %edi     /* edi = clipmask */
  1350.     movl 16(%esp), %esi     /* esi = d */
  1351.  
  1352.     call cliptest
  1353.  
  1354.     movl 32(%esp), %edi     /* ormask */
  1355.     movl 36(%esp), %esi     /* andmask */
  1356.     movb %al, (%edi)
  1357.     movb %ah, (%esi)
  1358.  
  1359.     popl %edi
  1360.     popl %esi
  1361.     ret
  1362.  
  1363.  
  1364. /*
  1365.  * void asm_project_and_cliptest_identity( GLuint n, GLfloat d[][4],
  1366.  *                                         GLfloat s[][4], GLubyte clipmask[],
  1367.  *                                         GLubyte *ormask, GLubyte *andmask );
  1368.  */
  1369. #ifdef FREEBSD
  1370. GLOBAL(_asm_project_and_cliptest_identity)
  1371. ALIGN
  1372. _asm_project_and_cliptest_identity:
  1373. #else
  1374. GLOBAL(asm_project_and_cliptest_identity)
  1375. ALIGN
  1376. asm_project_and_cliptest_identity:
  1377. #endif
  1378.     pushl %esi
  1379.     pushl %edi
  1380.     movl 12(%esp), %ecx     /* ecx = n */
  1381.     movl 16(%esp), %edi     /* edi = d */
  1382.     movl 20(%esp), %esi     /* esi = s */
  1383.  
  1384.     pushl %esi
  1385.     pushl %edi
  1386.     pushl %ecx
  1387. #ifdef FREEBSD
  1388.     call _asm_transform_points4_identity
  1389. #else
  1390.     call asm_transform_points4_identity
  1391. #endif
  1392.     addl $12, %esp
  1393.  
  1394.     movl 28(%esp), %edi     /* ormask */
  1395.     movl 32(%esp), %esi     /* andmask */
  1396.     movb (%edi), %al
  1397.     movb (%esi), %ah
  1398.  
  1399.     movl 12(%esp), %ecx     /* ecx = n */
  1400.     movl 24(%esp), %edi     /* edi = clipmask */
  1401.     movl 16(%esp), %esi     /* esi = d */
  1402.  
  1403.     call cliptest
  1404.  
  1405.     movl 28(%esp), %edi     /* ormask */
  1406.     movl 32(%esp), %esi     /* andmask */
  1407.     movb %al, (%edi)
  1408.     movb %ah, (%esi)
  1409.  
  1410.     popl %edi
  1411.     popl %esi
  1412.     ret
  1413.  
  1414. /*
  1415.  * void asm_project_and_cliptest_ortho( GLuint n, GLfloat d[][4], GLfloat m[16],
  1416.  *                                      GLfloat s[][4], GLubyte clipmask[],
  1417.  *                                      GLubyte *ormask, GLubyte *andmask );
  1418.  */
  1419. #ifdef FREEBSD
  1420. GLOBAL(_asm_project_and_cliptest_ortho)
  1421. ALIGN
  1422. _asm_project_and_cliptest_ortho:
  1423. #else
  1424. GLOBAL(asm_project_and_cliptest_ortho)
  1425. ALIGN
  1426. asm_project_and_cliptest_ortho:
  1427. #endif
  1428.     pushl %esi
  1429.     pushl %edi
  1430.     movl 12(%esp), %ecx     /* ecx = n */
  1431.     movl 16(%esp), %edi     /* edi = d */
  1432.     movl 20(%esp), %edx     /* edx = m */
  1433.     movl 24(%esp), %esi     /* esi = s */
  1434.  
  1435.     pushl %esi
  1436.     pushl %edx
  1437.     pushl %edi
  1438.     pushl %ecx
  1439. #ifdef FREEBSD
  1440.     call _asm_transform_points4_ortho
  1441. #else
  1442.     call asm_transform_points4_ortho
  1443. #endif
  1444.     addl $16, %esp
  1445.  
  1446.     movl 32(%esp), %edi     /* ormask */
  1447.     movl 36(%esp), %esi     /* andmask */
  1448.     movb (%edi), %al
  1449.     movb (%esi), %ah
  1450.  
  1451.     movl 12(%esp), %ecx     /* ecx = n */
  1452.     movl 28(%esp), %edi     /* edi = clipmask */
  1453.     movl 16(%esp), %esi     /* esi = d */
  1454.  
  1455.     call cliptest
  1456.  
  1457.     movl 32(%esp), %edi     /* ormask */
  1458.     movl 36(%esp), %esi     /* andmask */
  1459.     movb %al, (%edi)
  1460.     movb %ah, (%esi)
  1461.  
  1462.     popl %edi
  1463.     popl %esi
  1464.     ret
  1465.  
  1466. /*
  1467.  * void asm_project_and_cliptest_perspective( GLuint n, GLfloat d[][4], GLfloat m[16],
  1468.  *                                            GLfloat s[][4], GLubyte clipmask[],
  1469.  *                                            GLubyte *ormask, GLubyte *andmask );
  1470.  */
  1471. #ifdef FREEBSD
  1472. GLOBAL(_asm_project_and_cliptest_perspective)
  1473. ALIGN
  1474. _asm_project_and_cliptest_perspective:
  1475. #else
  1476. GLOBAL(asm_project_and_cliptest_perspective)
  1477. ALIGN
  1478. asm_project_and_cliptest_perspective:
  1479. #endif
  1480.     pushl %esi
  1481.     pushl %edi
  1482.     movl 12(%esp), %ecx     /* ecx = n */
  1483.     movl 16(%esp), %edi     /* edi = d */
  1484.     movl 20(%esp), %edx     /* edx = m */
  1485.     movl 24(%esp), %esi     /* esi = s */
  1486.  
  1487.     pushl %esi
  1488.     pushl %edx
  1489.     pushl %edi
  1490.     pushl %ecx
  1491. #ifdef FREEBSD
  1492.     call _asm_transform_points4_perspective
  1493. #else
  1494.     call asm_transform_points4_perspective
  1495. #endif
  1496.     addl $16, %esp
  1497.  
  1498.     movl 32(%esp), %edi     /* ormask */
  1499.     movl 36(%esp), %esi     /* andmask */
  1500.     movb (%edi), %al
  1501.     movb (%esi), %ah
  1502.  
  1503.     movl 12(%esp), %ecx     /* ecx = n */
  1504.     movl 28(%esp), %edi     /* edi = clipmask */
  1505.     movl 16(%esp), %esi     /* esi = d */
  1506.  
  1507.     call cliptest
  1508.  
  1509.     movl 32(%esp), %edi     /* ormask */
  1510.     movl 36(%esp), %esi     /* andmask */
  1511.     movb %al, (%edi)
  1512.     movb %ah, (%esi)
  1513.  
  1514.     popl %edi
  1515.     popl %esi
  1516.     ret
  1517.  
  1518.  
  1519. /*
  1520.  * unsigned int inverse_nofp( float f );
  1521.  *
  1522.  * Calculate the inverse of a float without using the FPU.
  1523.  * This function returns a float in eax, so it's return
  1524.  * type should be 'int' when called from C (and converted
  1525.  * to float with pointer/union abuse).
  1526.  */
  1527. ALIGN
  1528. inverse_nofp:
  1529.  
  1530.     /* get mantissa in eax */
  1531.     movl 4(%esp), %ecx
  1532.     andl $0x7fffff, %ecx
  1533.  
  1534.     /* set implicit integer */
  1535.     orl $0x800000, %ecx
  1536.  
  1537.     /* div 0x10000:0x00000000 by mantissa */
  1538.     xorl %eax, %eax
  1539.     movl $0x10000, %edx
  1540.  
  1541.     divl %ecx
  1542.     
  1543.     /* round result */
  1544.     shrl $1, %eax
  1545.     adcl $0, %eax
  1546.  
  1547.     /* get exponent in ecx */
  1548.     movl $0x7f800000, %ecx
  1549.     movl 4(%esp), %edx
  1550.     andl %edx, %ecx
  1551.  
  1552.     /* negate exponent and decrement it */
  1553.     movl $253 << 23, %edx
  1554.     subl %ecx, %edx
  1555.  
  1556.     /* if bit 24 is set, shift and adjust exponent */
  1557.     testl $0x1000000, %eax
  1558.     jz 1f
  1559.  
  1560.     shrl $1, %eax
  1561.     addl $1 << 23, %edx
  1562.  
  1563.     /* combine mantissa and exponent, then set sign */
  1564. 1:    andl $0x7fffff, %eax
  1565.     movl 4(%esp), %ecx
  1566.     orl %edx, %eax
  1567.     andl $0x80000000, %ecx
  1568.     orl %ecx, %eax
  1569.  
  1570.     ret
  1571.  
  1572.  
  1573. /*
  1574.  * void gl_xform_normals_3fv( GLuint n, GLfloat d[][4], GLfloat m[16],
  1575.  *                            GLfloat s[][4], GLboolean normalize,
  1576.  *                            GLboolean rescale );
  1577.  */
  1578. #ifdef FREEBSD
  1579. GLOBAL(_gl_xform_normals_3fv)
  1580. ALIGN
  1581. _gl_xform_normals_3fv:
  1582. #else
  1583. GLOBAL(gl_xform_normals_3fv)
  1584. ALIGN
  1585. gl_xform_normals_3fv:
  1586. #endif
  1587.     pushl %esi
  1588.     pushl %edi
  1589.     movl 12(%esp), %ecx     /* ecx = n */
  1590.     movl 16(%esp), %edi     /* edi = d */
  1591.     movl 20(%esp), %edx     /* edx = m */
  1592.     movl 24(%esp), %esi     /* esi = s */
  1593.  
  1594.     testl %ecx, %ecx
  1595.     jz 2f
  1596.  
  1597.     /*
  1598.      * Check if rescale is needed
  1599.      */
  1600.     cmpl $0, 32(%esp)
  1601.     jz 3f
  1602.  
  1603.     /*
  1604.      * Transform and rescale
  1605.      */
  1606.     flds M(0, 2)
  1607.     fmuls M(0, 2)
  1608.     flds M(1, 2)
  1609.     fmuls M(1, 2)
  1610.     flds M(2, 2)
  1611.     fmuls M(2, 2)
  1612.     fxch
  1613.     faddp %st(2)
  1614.     faddp %st(1)
  1615.     fsqrt
  1616.     fld1
  1617.     fdivp %st, %st(1)
  1618.  
  1619. 1:    flds S(0)
  1620.     fmuls M(0, 0)
  1621.     flds S(0)
  1622.     fmuls M(1, 0)
  1623.     flds S(0)
  1624.     fmuls M(2, 0)
  1625.  
  1626.     flds S(1)
  1627.     fmuls M(0, 1)
  1628.     flds S(1)
  1629.     fmuls M(1, 1)
  1630.     flds S(1)
  1631.     fmuls M(2, 1)
  1632.  
  1633.     /*
  1634.      * st(5) = S(0) * M(0, 0)
  1635.      * st(4) = S(0) * M(1, 0)
  1636.      * st(3) = S(0) * M(2, 0)
  1637.      * st(2) = S(1) * M(0, 1)
  1638.      * st(1) = S(1) * M(1, 1)
  1639.      * st(0) = S(1) * M(2, 1)
  1640.      */
  1641.  
  1642.     fxch %st(2)         /* 2 1 0 3 4 5 */
  1643.     faddp %st, %st(5)     /* 1 0 3 4 5 */
  1644.     faddp %st, %st(3)     /* 0 3 4 5 */
  1645.     faddp %st, %st(1)     /* 3 4 5 */
  1646.  
  1647.     /*
  1648.      * st(2) = S(0) * M(0, 0) + S(1) * M(0, 1)
  1649.      * st(1) = S(0) * M(1, 0) + S(1) * M(1, 1)
  1650.      * st(0) = S(0) * M(2, 0) + S(1) * M(2, 1)
  1651.      */
  1652.  
  1653.     flds S(2)
  1654.     fmuls M(0, 2)
  1655.     flds S(2)
  1656.     fmuls M(1, 2)
  1657.     flds S(2)
  1658.     fmuls M(2, 2)
  1659.  
  1660.     /*
  1661.      * st(5) = S(0) * M(0, 0) + S(1) * M(0, 1)
  1662.      * st(4) = S(0) * M(1, 0) + S(1) * M(1, 1)
  1663.      * st(3) = S(0) * M(2, 0) + S(1) * M(2, 1)
  1664.      * st(2) = S(2) * M(0, 2)
  1665.      * st(1) = S(2) * M(1, 2)
  1666.      * st(0) = S(2) * M(2, 2)
  1667.      */
  1668.  
  1669.     fxch %st(2)         /* 2 1 0 3 4 5 */
  1670.     faddp %st, %st(5)     /* 1 0 3 4 5 */
  1671.     faddp %st, %st(3)     /* 0 3 4 5 */
  1672.     faddp %st, %st(1)     /* 3 4 5 */
  1673.  
  1674.     /*
  1675.      * st(2) = S(0) * M(0, 0) + S(1) * M(0, 1) + S(2) * M(0, 2)
  1676.      * st(1) = S(0) * M(1, 0) + S(1) * M(1, 1) + S(2) * M(1, 2)
  1677.      * st(0) = S(0) * M(2, 0) + S(1) * M(2, 1) + S(2) * M(2, 2)
  1678.      */
  1679.  
  1680.     fld %st(3)
  1681.     fmul %st, %st(1)
  1682.     fmul %st, %st(2)
  1683.     fmulp %st(3)
  1684.  
  1685.     fstps D(2)
  1686.     fstps D(1)
  1687.     fstps D(0)
  1688.  
  1689.     leal S(3), %esi
  1690.     decl %ecx
  1691.  
  1692.     leal D(3), %edi
  1693.  
  1694.     jnz 1b
  1695.  
  1696.     fstp %st(0)
  1697.  
  1698.     jmp 4f
  1699.  
  1700.     /*
  1701.      * Transform (no rescale)
  1702.      */
  1703. ALIGN
  1704. 3:    flds S(0)
  1705.     fmuls M(0, 0)
  1706.     flds S(0)
  1707.     fmuls M(1, 0)
  1708.     flds S(0)
  1709.     fmuls M(2, 0)
  1710.  
  1711.     flds S(1)
  1712.     fmuls M(0, 1)
  1713.     flds S(1)
  1714.     fmuls M(1, 1)
  1715.     flds S(1)
  1716.     fmuls M(2, 1)
  1717.  
  1718.     /*
  1719.      * st(5) = S(0) * M(0, 0)
  1720.      * st(4) = S(0) * M(1, 0)
  1721.      * st(3) = S(0) * M(2, 0)
  1722.      * st(2) = S(1) * M(0, 1)
  1723.      * st(1) = S(1) * M(1, 1)
  1724.      * st(0) = S(1) * M(2, 1)
  1725.      */
  1726.  
  1727.     fxch %st(2)         /* 2 1 0 3 4 5 */
  1728.     faddp %st, %st(5)     /* 1 0 3 4 5 */
  1729.     faddp %st, %st(3)     /* 0 3 4 5 */
  1730.     faddp %st, %st(1)     /* 3 4 5 */
  1731.  
  1732.     /*
  1733.      * st(2) = S(0) * M(0, 0) + S(1) * M(0, 1)
  1734.      * st(1) = S(0) * M(1, 0) + S(1) * M(1, 1)
  1735.      * st(0) = S(0) * M(2, 0) + S(1) * M(2, 1)
  1736.      */
  1737.  
  1738.     flds S(2)
  1739.     fmuls M(0, 2)
  1740.     flds S(2)
  1741.     fmuls M(1, 2)
  1742.     flds S(2)
  1743.     fmuls M(2, 2)
  1744.  
  1745.     /*
  1746.      * st(5) = S(0) * M(0, 0) + S(1) * M(0, 1)
  1747.      * st(4) = S(0) * M(1, 0) + S(1) * M(1, 1)
  1748.      * st(3) = S(0) * M(2, 0) + S(1) * M(2, 1)
  1749.      * st(2) = S(2) * M(0, 2)
  1750.      * st(1) = S(2) * M(1, 2)
  1751.      * st(0) = S(2) * M(2, 2)
  1752.      */
  1753.  
  1754.     fxch %st(2)         /* 2 1 0 3 4 5 */
  1755.     faddp %st, %st(5)     /* 1 0 3 4 5 */
  1756.     faddp %st, %st(3)     /* 0 3 4 5 */
  1757.     faddp %st, %st(1)     /* 3 4 5 */
  1758.  
  1759.     /*
  1760.      * st(2) = S(0) * M(0, 0) + S(1) * M(0, 1) + S(2) * M(0, 2)
  1761.      * st(1) = S(0) * M(1, 0) + S(1) * M(1, 1) + S(2) * M(1, 2)
  1762.      * st(0) = S(0) * M(2, 0) + S(1) * M(2, 1) + S(2) * M(2, 2)
  1763.      */
  1764.  
  1765.     fxch %st(2)     /* 2 1 0 */
  1766.     fstps D(0)     /* 1 0 */
  1767.     fstps D(1)     /* 0 */
  1768.     fstps D(2)     /* */
  1769.  
  1770.     leal S(3), %esi
  1771.     decl %ecx
  1772.  
  1773.     leal D(3), %edi
  1774.  
  1775.     jnz 3b
  1776.  
  1777.     /*
  1778.      * Skip normalize if it isn't needed
  1779.      */
  1780. 4:    cmpl $0, 28(%esp)
  1781.     jz 2f
  1782.  
  1783.     /* Normalize required */
  1784.  
  1785.     movl 12(%esp), %esi     /* esi = n */
  1786.     movl 16(%esp), %edi     /* edi = d */
  1787.  
  1788.     subl $4, %esp     /* temp var for 1.0 / len */
  1789.  
  1790.     /*
  1791.      * (%esp) = length of first normal
  1792.      */
  1793.     flds D(0)
  1794.     fmuls D(0)
  1795.     flds D(1)
  1796.     fmuls D(1)
  1797.     flds D(2)
  1798.     fmuls D(2)
  1799.     fxch %st(2)
  1800.     faddp %st(1)
  1801.     faddp %st(1)
  1802.     fsqrt
  1803.     fstps (%esp)
  1804.  
  1805.     jmp 3f
  1806.  
  1807. ALIGN
  1808. 1:    /* %st(0) = length of next normal */
  1809.     flds D(3)
  1810.     fmuls D(3)
  1811.     flds D(4)
  1812.     fmuls D(4)
  1813.     flds D(5)
  1814.     fmuls D(5)
  1815.     fxch %st(2)
  1816.     faddp %st(1)
  1817.     faddp %st(1)
  1818.     fsqrt
  1819.  
  1820.     /*
  1821.      * inverse the length of the current normal, which is
  1822.      * already at (%esp).  This should overlap the prev
  1823.      * fsqrt nicely.
  1824.      */
  1825.     call inverse_nofp
  1826.     movl %eax, (%esp)
  1827.  
  1828.     /* multiply normal by 1/len */
  1829.     flds D(0)
  1830.     fmuls (%esp)
  1831.     flds D(1)
  1832.     fmuls (%esp)
  1833.     flds D(2)
  1834.     fmuls (%esp)
  1835.     fxch %st(3)
  1836.     fstps (%esp)     /* store length of next normal */
  1837.     fstps D(1)
  1838.     fstps D(0)
  1839.     fstps D(2)
  1840.     leal D(3), %edi
  1841. 3:    decl %esi
  1842.     jnz 1b
  1843.  
  1844.     /* finish up the last normal */
  1845.     call inverse_nofp
  1846.     movl %eax, (%esp)
  1847.     flds D(0)
  1848.     fmuls (%esp)
  1849.     flds D(1)
  1850.     fmuls (%esp)
  1851.     flds D(2)
  1852.     fmuls (%esp)
  1853.     fxch %st(2)
  1854.     fstps D(0)
  1855.     fstps D(1)
  1856.     fstps D(2)
  1857.  
  1858.     addl $4, %esp
  1859.  
  1860. 2:    popl %edi
  1861.     popl %esi
  1862.     ret
  1863.  
  1864. /* end */
  1865.